﻿using UnityEngine;
using UnityEngine.UIElements;

namespace winS.UnityEditor.UIElement
{
    public class Vector4Field : EditorField<Vector4>
    {
        public Label labelX => xField.label;
        public Label labelY => yField.label;
        public Label labelZ => zField.label;
        public Label labelW => wField.label;

        private readonly FloatField xField;
        private readonly FloatField yField;
        private readonly FloatField zField;
        private readonly FloatField wField;

        public Vector4Field(ElementFactory elementFactory) : base(elementFactory)
        {
            float width = 1f / 4f;
            //X
            Add(xField = EditorElementUtility.elementFactory.CreateFloatField("X", OnXChangedCallback));
            EditorElementUtility.ApplySubFieldStyle(xField);
            xField.style.SetWidth(width, LengthUnit.Percent);
            //Y
            Add(yField = EditorElementUtility.elementFactory.CreateFloatField("Y", OnYChangedCallback));
            EditorElementUtility.ApplySubFieldStyle(yField);
            yField.style.marginLeft = 6f;
            yField.style.SetWidth(width, LengthUnit.Percent);
            //Z
            Add(zField = EditorElementUtility.elementFactory.CreateFloatField("Z", OnZChangedCallback));
            EditorElementUtility.ApplySubFieldStyle(zField);
            zField.style.marginLeft = 6f;
            zField.style.SetWidth(width, LengthUnit.Percent);
            //W
            Add(wField = EditorElementUtility.elementFactory.CreateFloatField("W", OnWChangedCallback));
            EditorElementUtility.ApplySubFieldStyle(wField);
            wField.style.marginLeft = 6f;
            wField.style.SetWidth(width, LengthUnit.Percent);
        }

        public override void SetValueWithoutNotify(Vector4 value)
        {
            base.SetValueWithoutNotify(value);
            SetDisplayValue(value);
        }

        protected override void SetValue(Vector4 value)
        {
            base.SetValue(value);
            SetDisplayValue(value);
        }
        protected override void OnRedo(Vector4 newValue)
        {
            base.OnRedo(newValue);
            SetDisplayValue(newValue);
        }
        protected override void OnUndo(Vector4 oldValue)
        {
            base.OnUndo(oldValue);
            SetDisplayValue(oldValue);
        }

        private void SetDisplayValue(Vector4 value)
        {
            xField.SetValueWithoutNotify(value.x);
            yField.SetValueWithoutNotify(value.y);
            zField.SetValueWithoutNotify(value.z);
            wField.SetValueWithoutNotify(value.w);
        }
        private void OnXChangedCallback(float newValue)
        {
            Vector4 currentValue = value;
            currentValue.x = newValue;
            base.SetValue(currentValue);
        }
        private void OnYChangedCallback(float newValue)
        {
            Vector4 currentValue = value;
            currentValue.y = newValue;
            base.SetValue(currentValue);
        }
        private void OnZChangedCallback(float newValue)
        {
            Vector4 currentValue = value;
            currentValue.z = newValue;
            base.SetValue(currentValue);
        }
        private void OnWChangedCallback(float newValue)
        {
            Vector4 currentValue = value;
            currentValue.w = newValue;
            base.SetValue(currentValue);
        }
    }
}